//
//  PlayAudioManager.m
//  RainbowFM
//
//  Created by Kratos on 14/12/30.
//  Copyright (c) 2014年 RB. All rights reserved.
//

#import "PlayAudioManager.h"
#import "SpeexCodeUtility.h"


@interface PlayAudioManager () <AVAudioPlayerDelegate>
{
    AVAudioPlayer *player_ ; // 录音变量
    NSMutableDictionary *playSetting_; // 录音设置
    
    NSString *storePath_; // 录音文件存储路径
    NSTimeInterval beginInterval_; // 录音开始时间戳
    NSTimeInterval endInterval_; // 录音结束时间戳
    
    NSLock *locker_ ; // 锁
}
@end

@implementation PlayAudioManager

@synthesize player = player_;

+ (PlayAudioManager*)sharedManager
{
    static PlayAudioManager *shareManager = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        shareManager = [[self alloc] init];
    });
    
    return shareManager;
}

// 初始化播放session
- (void)initPlaySession
{
    //    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    //
    //    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    //    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    //
    //    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    
    
    
    //get your app's audioSession singleton object
    AVAudioSession* session = [AVAudioSession sharedInstance];
    
    //error handling
    BOOL success;
    NSError* error;
    
    //set the audioSession category.
    //Needs to be Record or PlayAndRecord to use audioRouteOverride:
    success = [session setCategory:AVAudioSessionCategoryPlayAndRecord
                             error:&error];
    if (! success) {
        NSLog(@"AVAudioSession error setting category:%@",error);
    }
    
    //set the audioSession override
    success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                         error:&error];
    if (! success) {
        NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);
    }
    
    //activate the audio session
    success = [session setActive:YES error:&error];
    if (! success) {
        NSLog(@"AVAudioSession error activating: %@",error);
    } else {
        NSLog(@"audioSession active");
    }
    
    
    [self startProximityMonitering];
}

- (id) init
{
    if (self = [super init]) {
        // 耳朵靠近切换扬声器和耳机播放
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(sensorStateChange:)
                                                     name:@"UIDeviceProximityStateDidChangeNotification"
                                                   object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(willResignActive:)
                                                     name:UIApplicationWillResignActiveNotification
                                                   object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(didBecomeActive:)
                                                     name:UIApplicationDidBecomeActiveNotification
                                                   object:nil];
    }
    
    return self;
}

- (void)dealloc
{
    if (player_) {
        if ([player_ isPlaying]) {
            [player_ stop];
        }
        
        player_.delegate = nil;
        player_ = nil;
    }
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - 外部调用的播放、停止播放函数
- (void)playAudioWithFilePath:(NSString *)filePath success:(void(^)(BOOL success))result
{
    if (player_) {
        if ([player_ isPlaying]) {
            [player_ stop];
            
            if (_delegatePlayingCompleteOrUserStop && [_delegatePlayingCompleteOrUserStop respondsToSelector:@selector(playingCompleteOrUserStopWithFile:)]) {
                [_delegatePlayingCompleteOrUserStop playingCompleteOrUserStopWithFile:storePath_];
            }
        }
        
        player_.delegate = nil;
        player_ = nil;
    }
    
    if (! filePath) {
        if (result) {
            result(NO);
        }
        return;
    }
    
    NSData * speexData = nil;
    
    speexData = [self cachedDataWithLocalPath:filePath];
    
    if (speexData == nil) {
        if (result) {
            result(NO);
        }
        return;
    }
    
    
    NSError *error;
    
    //    NSString * pathfile = [[BLKVoiceTransfer sharedTransfer] md5StringPathWithURL:filePath];
    
    NSData * wavData = decodeSpeex2WAVE(speexData);
    player_ = [[AVAudioPlayer alloc] initWithData:wavData error:&error];
    [player_ setMeteringEnabled:YES];
    if (player_) {
        player_.volume = 1.0;
        
        [self initPlaySession];
        
        player_.delegate = self;
        [player_ play];
        
        storePath_ = filePath;
        
        if (result) {
            result(YES);
        }
    } else {
        if (result) {
            result(NO);
        }
    }
}

- (void)playAudioWithSpeexData:(NSData *)speexData;
{
    if (player_) {
        if ([player_ isPlaying]) {
            [player_ stop];
        }
        
        player_.delegate = nil;
        player_ = nil;
    }
    
    if (! speexData) {
        return;
    }
    
//    NSData *cafData = decodeSpeex2WAVE(speexData);
    
    NSError *error;
    player_ = [[AVAudioPlayer alloc] initWithData:speexData error:&error];
    [player_ setMeteringEnabled:YES];
    if (player_) {
        player_.volume = 1.0;
        
        [self initPlaySession];
        
        player_.delegate = self;
        [player_ play];
    }
}

- (BOOL)isPlaying
{
    return [player_ isPlaying];
}

- (void)pausePlaying
{
    [player_ pause];
}

- (void)resumePlaying
{
    player_.volume = 1.0;
    [self initPlaySession];
    
    [player_ play];
}

- (void)stopPlaying
{
    [self stopProximityMonitering];
    
    if (player_) {
        if ([player_ isPlaying]) {
            [player_ stop];
            
            if (_delegatePlayingCompleteOrUserStop && [_delegatePlayingCompleteOrUserStop respondsToSelector:@selector(playingCompleteOrUserStopWithFile:)]) {
                [_delegatePlayingCompleteOrUserStop playingCompleteOrUserStopWithFile:storePath_];
            }
        }
        
        player_.delegate = nil;
        player_ = nil;
    }
}

#pragma mark - 耳朵靠近手机时，扬声器和耳机播放切换
- (void)sensorStateChange:(NSNotification *)notification {
    // 如果此时手机靠近面部放在耳朵旁，那么声音将通过听筒输出，并将屏幕变暗
    if ([[UIDevice currentDevice] proximityState] == YES) {
        //[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [self updatePlaySessionWithEarNearFlag:YES];
        
        NSLog(@"设备靠近耳朵");
    } else {
        //[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
        [self updatePlaySessionWithEarNearFlag:NO];
        
        NSLog(@"设备远离耳朵...");
    }
}

- (void)updatePlaySessionWithEarNearFlag:(BOOL)bEarNearFlag
{
    //get your app's audioSession singleton object
    AVAudioSession* session = [AVAudioSession sharedInstance];
    
    //error handling
    BOOL success;
    NSError* error;
    
    //set the audioSession override
    if (bEarNearFlag) {
        success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
    } else {
        success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
    }
    
    if (! success) {
        NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);
    }
    
    //activate the audio session
    success = [session setActive:YES error:&error];
    if (! success) {
        NSLog(@"AVAudioSession error activating: %@",error);
    } else {
        NSLog(@"audioSession active");
    }
}

- (void)startProximityMonitering {
    [[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
    
    NSLog(@"开启距离监听");
}

- (void)stopProximityMonitering {
    [[UIDevice currentDevice] setProximityMonitoringEnabled:NO];
    
    NSLog(@"关闭距离监听。。。");
}

#pragma mark - AVAudioPlayerDelegate
// 播放完成调用，用户stop和其他中断stop不调用
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    [self stopProximityMonitering];
    
    if (_delegatePlayingCompleteOrUserStop && [_delegatePlayingCompleteOrUserStop respondsToSelector:@selector(playingCompleteOrUserStopWithFile:)]) {
        [_delegatePlayingCompleteOrUserStop playingCompleteOrUserStopWithFile:storePath_];
    }
    
    if (player_) {
        player_.delegate = nil;
        player_ = nil;
    }
}

- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
    [[AVAudioSession sharedInstance] setActive:NO error:nil];
    
    [player_ pause];
}

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags
{
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    
    [player_ play];
}

#pragma mark - NSNotification
-(void)willResignActive:(NSNotification*)notify
{
    [self stopPlaying];
}

-(void)didBecomeActive:(NSNotification*)notify
{
    
}

- (NSData*) cachedDataWithLocalPath:(NSString *)path
{
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        return [NSData dataWithContentsOfFile:path];
    }
    
    NSString * voicePath_ = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"/voices/"];
    
    NSArray* splits = [path componentsSeparatedByString:@"/Documents/voices"];
    if (splits.count < 2) {
        return nil;
    }
    
    NSString* truePath = [voicePath_ stringByAppendingPathComponent:splits[1]];
    return [NSData dataWithContentsOfFile:truePath];
}

@end

